import type { LoadingInstance } from 'element-plus/es/components/loading/src/loading'
import type {
  LoopInfoMapPropsType,
  LoopInfoMapLightPoleType,
  LoopInfoMapMarkerEventType,
  LoopInfoMapStateType
} from './typings'
import { defineComponent, ref, reactive, onMounted, onBeforeUnmount, shallowRef } from 'vue'
import { useStore } from 'vuex'
import {
  keys
  // values
} from 'lodash'
import { ElLoading, ElButton } from 'element-plus'
import MapToolbar from '~/components/MapToolbar'
import AliIcon from '~/components/AliIocn'
import useAMap from '~/hooks/useAMap'
import useVuexGetters from '~/hooks/useVuexGetters'
import equipmentCenterIcon from '~/assets/equipmentCenter.png'
import lightPoleIcon from '~/assets/lightPoleOn.png'
import styles from '../../index.module.scss'

export default defineComponent({
  name: 'LoopInfoMap',
  props: ['id', 'detail', 'toolbarVisible', 'strokeColor', 'initLoopInfo'],
  emits: ['changeLightPoleVisible'],
  setup(props: LoopInfoMapPropsType, { emit, expose }) {
    const store = useStore()
    const screenDomRef = ref()
    const mapToolbarRef = ref()
    const lamppost = shallowRef()
    const loadRef = ref<LoadingInstance>()
    const state = reactive<LoopInfoMapStateType>({
      lightPoleShow: false,
      polesIds: {},
      lamppostMarker: {}
    })
    const userState = useVuexGetters('user', ['userAddressInfo'])

    const [mapRef, aMapRef] = useAMap(
      props.id!,
      {
        dragEnable: true,
        doubleClickZoom: false,
        center: [userState.userAddressInfo.value.lon, userState.userAddressInfo.value.lat],
        zoom: 14
      },
      initAMap
    )

    // 点击灯杆标记点的回调
    const handleClickLightPole = (e: LoopInfoMapMarkerEventType) => {
      if (mapToolbarRef.value?.eventState.contactLinkPattern) {
        mapToolbarRef.value?.setContactPointPolyline(e.target.getPosition())
      } else {
        mapToolbarRef.value?.setPolylinePath(e.target.getPosition())
      }
      const { strokeColor } = props
      const extData = e.target.getExtData()
      if (!state.polesIds[strokeColor]?.includes(strokeColor)) {
        if (state.polesIds[strokeColor]?.length) {
          state.polesIds[strokeColor].push(extData?.id!)
        } else {
          state.polesIds[strokeColor] = [extData?.id!]
        }
      }
    }

    // 点击配电设施点的回调
    const handleClickEquipmentCenter = (e: LoopInfoMapMarkerEventType) => {
      if (mapToolbarRef.value?.eventState.contactLinkPattern) {
        mapToolbarRef.value?.setContactPointPolyline(e.target.getPosition())
      } else {
        mapToolbarRef.value?.setPolylinePath(e.target.getPosition())
      }
    }

    // 为地图添加配电设施中心标记点
    const handleAddEquipmentCenter = () => {
      mapRef.value.setCenter([props.detail.lon, props.detail.lat])
      const equipmentCenter = new aMapRef.value.Marker({
        map: mapRef.value,
        icon: new aMapRef.value.Icon({
          size: new aMapRef.value.Size(32, 32),
          imageSize: new aMapRef.value.Size(32, 32),
          image: equipmentCenterIcon
        }),
        title: props.detail.name,
        position: [props.detail.lon, props.detail.lat],
        offset: [-16, -16],
        bubble: true
        // zooms: [2, 20]
      })
      equipmentCenter?.on('click', handleClickEquipmentCenter)
      // mapRef.value.setFitView()
    }

    // 切换灯杆显示
    const handleChangeShowLightPole = (visible: boolean) => {
      state.lightPoleShow = visible
      if (state.lightPoleShow) {
        // values(state.lightPoles)?.forEach?.((item: Record<string, any>) => {
        //   item.show()
        // })
        lamppost.value.show()
      } else {
        // values(state.lightPoles)?.forEach?.((item: Record<string, any>) => {
        //   item.hide()
        // })
        lamppost.value.hide()
      }
    }

    // 根据传入灯杆id数组显示对应的灯杆
    const handleChangeShowLightPoleByPoleIds = (ids: string[] = []) => {
      if (state.lightPoles) {
        state.lightPoleShow = false
        keys(state.lightPoles).forEach((key: string) => {
          if (ids.includes(key)) {
            state.lightPoles!?.[key].show()
          } else {
            state.lightPoles!?.[key].hide()
          }
        })
      }
    }

    // 获取灯杆列表用于地图灯杆展示
    const handleGetLightPoleList = async () => {
      // 根据详情信息获取当前配电设施的所有灯杆
      const bounds = mapRef.value.getBounds()
      // 西北（左上）
      const northWest = bounds.getNorthWest()
      // 东南（右下）
      const southEast = bounds.getSouthEast()

      const params = {
        distributionId: props.detail.id,
        streetId: props.detail.streetId,
        workAreaId: props.detail.workAreaId,
        leftLatitude: northWest.lat,
        leftLongitude: northWest.lng,
        rightLatitude: southEast.lat,
        rightLongitude: southEast.lng
      }
      const res = await store.dispatch('assetLampPost/GetLampPostSelectBoxListByKey', params)
      state.lightPoles = (res?.data || [])?.reduce(
        (poles: LoopInfoMapStateType['lightPoles'], item: LoopInfoMapLightPoleType) => {
          if (!item.lon || !item.lat || !item.id) return poles
          if (state.lamppostMarker?.[item.id]) return poles
          state.lamppostMarker[item.id] = item
          poles![item.id] = new aMapRef.value.LabelMarker({
            icon: {
              type: 'image',
              image: lightPoleIcon,
              size: [34, 34],
              offset: [20, 20]
            },
            // title: item.name,
            position: [item.lon, item.lat],
            extData: item || {}
            // offset: [-17, -34],
            // visible: false,
            // bubble: true
          })
          lamppost.value.add(poles![item.id])
          // mapRef.value.add(poles![item.id])
          poles![item.id].on('click', handleClickLightPole)
          return poles
        },
        {}
      )
    }

    // 将路径信息和路径包含的灯杆id都返回给调用的父组建
    const handleSubmitCurrentPattern = () => {
      const { strokeColor } = props
      // 首先关闭当前进行的操作
      mapToolbarRef.value?.clearToggleToolBarKey()
      // 之后获取路径并返回
      const patternInfo = mapToolbarRef.value?.drawPatterns?.[strokeColor]
      const loopPhase = {
        type: patternInfo?.type,
        coordinates: patternInfo?.pattern?.getPath?.()
      }
      return {
        loopPhase: !loopPhase?.coordinates?.length ? undefined : loopPhase,
        lampPostIds: state.polesIds[strokeColor] || []
      }
    }

    // 在编辑和删除的时候去判断回路里是否包含灯杆
    /* const handleChangeCurrentPattern = (paths: { lng: number; lat: number }[] = []) => {
      const { strokeColor } = props
      if (!state.polesIds[strokeColor]) return
      const filterPoles = state.polesIds[strokeColor]
        .map((id) => {
          if (state.lightPoles![id])
            return {
              ...state.lightPoles![id].getPosition(),
              id
            }
          return undefined
        })
        .filter(Boolean)
      // 去判断路径中是否包含路灯点 不包含则取消绑定
      state.polesIds[strokeColor] = filterPoles.reduce(
        (arr: string[], item: { lng: number; lat: number; id: string }) => {
          if (paths?.find((pathItem) => pathItem.lng === item.lng && pathItem.lat === item.lat))
            arr.push(item.id)
          return arr
        },
        []
      )
    } */

    // 切换回路颜色 并同时修改回路颜色绑定的灯杆
    const handleChangeLoopPatternColor = (currentStrokeColor: string, prevStrokeColor: string) => {
      if (state.polesIds[currentStrokeColor])
        state.polesIds[prevStrokeColor] = state.polesIds[currentStrokeColor]
      mapToolbarRef.value?.toChangePatternColor?.(currentStrokeColor, prevStrokeColor)
    }

    // 初始化map事件
    async function initAMap() {
      // 工具栏
      const toolBar = new aMapRef.value.ToolBar({
        visible: true,
        position: {
          top: '10px',
          right: '40px'
        }
      })
      // 将工具栏和工具栏方向盘添加到map中
      mapRef.value.addControl(toolBar)
      // 初始化路径
      const { initLoopInfo } = props
      if (initLoopInfo) {
        // 调用初始化方法
        keys(initLoopInfo).forEach((key: string) => {
          state.polesIds[key] = initLoopInfo[key]?.lampPostIds
          if (initLoopInfo[key]?.phase)
            mapToolbarRef.value?.initDrawPattern(key, initLoopInfo[key]?.phase)
        })
      }

      loadRef.value!.close()
      // 设置中心点
      handleAddEquipmentCenter()

      //  灯杆图层
      lamppost.value = new aMapRef.value.LabelsLayer({
        zooms: [3, 20],
        zIndex: 1000,
        // 开启标注避让，默认为开启，v1.4.15 新增属性
        collision: true
        // 开启标注淡入动画，默认为开启，v1.4.15 新增属性
        // animation: true,
      })
      mapRef.value.add(lamppost.value)
      lamppost.value.hide()

      // 开始获取灯杆列表
      setTimeout(() => {
        handleGetLightPoleList()
      }, 2000)
      mapRef.value.on('moveend', handleGetLightPoleList)
      mapRef.value.on('zoomend', () => {
        handleGetLightPoleList()
      })
    }

    onMounted(() => {
      loadRef.value = ElLoading.service({
        target: `#${props.id}`,
        text: '加载中'
      })
    })

    onBeforeUnmount(async () => {
      await mapRef.value.destroy()
    })

    expose({
      mapToolbar: mapToolbarRef,
      changeCurrentPattern: handleSubmitCurrentPattern,
      changeShowPoles: handleChangeShowLightPoleByPoleIds,
      changePolesVisible: handleChangeShowLightPole,
      changeLoopPatternColor: handleChangeLoopPatternColor
    })

    return () => (
      <section ref={screenDomRef} class={styles['loop-info-map-box']}>
        <section id={props.id}></section>
        <ElButton
          class={styles['loop-info-map-light-pole']}
          size="small"
          type={state.lightPoleShow ? 'primary' : 'default'}
          icon={<AliIcon type="icon-denggan" />}
          onClick={() => {
            handleChangeShowLightPole(!state.lightPoleShow)
            emit('changeLightPoleVisible', state.lightPoleShow)
          }}
        />
        <MapToolbar
          ref={mapToolbarRef}
          visible={props.toolbarVisible}
          mapRef={mapRef}
          aMapRef={aMapRef}
          screenDomRef={screenDomRef}
          strokeColor={props.strokeColor}
          center={[props.detail.lon, props.detail.lat]}
          // onChangePatternItemPath={handleChangeCurrentPattern}
        />
      </section>
    )
  }
})
